package com.learn.security.theory.signature;

import com.learn.security.utils.signature.DSAUtil;
import org.apache.commons.codec.binary.Hex;

import java.security.*;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;

/**
 * DSA签名
 */
public class DSATest {

    public static final String encodeStr = "DSA security is security";

    public static void main(String[] args) {

        dasUtil();
        jdkDSA();

    }

    // 用DASUtil实现：DSA签名
    private static void dasUtil() {
        String publicKey;
        String privateKey;

        // 构建密钥
        Map<String, Object> keyMap = DSAUtil.initKey();

        // 获得密钥
        publicKey = DSAUtil.getPublicKey(keyMap);
        privateKey = DSAUtil.getPrivateKey(keyMap);

        System.err.println("公钥:" + publicKey);
        System.err.println("私钥:" + privateKey);

        // 产生签名
        String sign = DSAUtil.sign(encodeStr.getBytes(), privateKey);
        System.err.println("签名:" + sign);

        // 验证签名
        Boolean status = DSAUtil.verify(encodeStr.getBytes(), publicKey, sign);
        System.err.println("状态:" + status);
    }


    /**
     * 用java的jdk里面相关方法实现dsa的签名及签名验证
     */
    private static void jdkDSA() {
        try {
            // 1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();
            DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();

            // 2.进行签名
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("DSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("SHA1withDSA");
            signature.initSign(privateKey);
            signature.update(encodeStr.getBytes());
            byte[] result = signature.sign();
            System.out.println("jdk dsa sign:" + Hex.encodeHexString(result));

            // 3.验证签名
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("DSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            signature = Signature.getInstance("SHA1withDSA");
            signature.initVerify(publicKey);
            signature.update(encodeStr.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("jdk dsa verify:" + bool);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

    }
}
